﻿/******************************************************************************
 * This file is part of libemb.
 *
 * libemb is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * libemb is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with libemb.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Project: Embedme
 * Author : FergusZeng
 * Email  : cblock@126.com
 * git	  : https://git.oschina.net/cblock/embedme
 * Copyright 2014~2017 @ ShenZhen ,China
*******************************************************************************/
#ifndef __CONFIG_H__
#define __CONFIG_H__

#include "BaseType.h"
#ifdef OS_ANDROID
#include "libconfigcpp.h"
#else
#include "libconfig.h++"
#endif
#include "Array.h"
#include "Mutex.h"

#include <iostream>
#include <vector>
using namespace std;

/*
 *                   Config Brief Introduce
 *
 * 配置文件的数据类型及格式:
 * 用大括号"{}"表示一组配置
 * 用分号";"隔开配置项
 * 同时支持C/C++/脚本三种风格的注释
 *---------------------------------------------------------------------
    int = 10001;                    //整形值
    double = 3.1415926;             //浮点值
    string = "Jim";                 //字符串
    int_array = [1,-1,1,0];         //数组,用[]表示,元素之间用逗号隔开
    double_array = [1.01, 2.02, 3.03];
    string_array = ["one","two","three"];
    list =                          //列表,用()包含,元素之间用逗号隔开
    (                          
        {item=1;},                  //list[0],配置项之间用分号隔开
        {item=2;name="Tom";},       //list[1],列表元素间用逗号隔开
     ); 
    group:                          //组配置,用{}包含
    {
        string ="fergus";           ###配置项之间用分号隔开
        subgroup:
        {
            array=[1,2,3,4];
        }
    }
 *---------------------------------------------------------------------
 *  整个文件是一个Setting,下面包含一个或多个Setting
 *  每个Setting里可以包含若干子Setting和其他数据类型
 */

/**
 *  \file   Config.h   
 *  \class  Settings
 *  \brief  配置项	
 */
class Config;
class Settings{
public:
    Settings();
    Settings(libconfig::Setting* root);
    Settings(const Settings&);
    virtual ~Settings();
    Settings operator[](int idx);
    Settings operator[](string name);
    bool isExist(string name);
    int size();
    int toInt();
    double toDouble();
    string toString();
    IntArray toIntArray();
    DoubleArray toDoubleArray();
    StringArray toStringArray();
    bool addInt(const string& keyname,int value=0);
    bool addDouble(const string& keyname,double value=0);
    bool addString(const string& keyname,const string& value="");
    bool addArray(const string& keyname,Array& value);
    bool addList(const string& keyname);
    bool addGroup(const string& keyname="");
    Settings& operator=(const int& value);
    Settings& operator=(const double& value);
    Settings& operator=(const string& value);
    Settings& operator=(IntArray& value);
    Settings& operator=(DoubleArray& value);
private:
    void setRoot(libconfig::Setting* root);
private:
    friend class Config;
    libconfig::Setting* m_root;
    string m_keyword;
};

/**
 *  \file   Config.h   
 *  \class  Config
 *  \brief  配置类	
 */
class Config{
public:
    Config();
    ~Config();
    bool initWithFile(const string& cfgFile);
    bool saveAsFile(const string& cfgFile);
    Settings operator[](string keyword);
    Settings rootSettings();
private:
    string m_filePath;
    libconfig::Config* m_config;
    libconfig::Setting* m_rootSetting;
    Settings* m_setting;
    Settings* m_nullsetting;
};


#endif
